package com.urea.common.utils.sign;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.Sign;
import cn.hutool.crypto.asymmetric.SignAlgorithm;
import cn.hutool.crypto.symmetric.AES;
import com.alibaba.fastjson2.JSONObject;
import com.google.common.collect.Lists;
import com.urea.common.exception.ServiceException;
import com.urea.common.utils.StringUtils;

import java.nio.charset.StandardCharsets;
import java.security.KeyPair;
import java.util.List;
import java.util.Objects;
import java.util.TreeMap;

/**
 * 类描述:
 * 支付相关的加解密以及签名
 *
 * @author fangXu
 * @version 1.0
 * @date 2023/8/22 17:34
 */
public class EncryptUtils {

    private static String AES_IV = "1122334455667788";
    private static String privateKeyBase64 = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC3u6RVZvq/e2ANNUzW09sqx5NpmkGH57M+am+z41IMnhJMqeNrUXwUbB4MvGRwLT1l91jJb8iLF5Kae7ULdEk5LIwa/UA3Ukov/3GBMRGkHLWDpjIc4i6zsPpBhH3Yn62it1wYrk01Aob5/s/Sx2vvHm1EnDX/aHgXoG8g+k0TNQbKB0GpzgCGDI6IGNoXRbdCh4y0eXnITiJTv1LtxWp6KSf636IX007SF5vcojMmjSwbphNXg1Si/DITAXAXTK7e4ZAhaxPgrAPa+D8QI2YTMaL9UwHjrZMdNKD7NnAHVaDl1zbelZJwfu2L7gNarEoafj4I7cGWLsdED/sO3mPbAgMBAAECggEAG8M5R4RU3avirYGWd5xcm4ARA3MrysGVQUMBAlFrm6d5BBI5tdotYcKdNHcfxXQ4jlihQb2SiTNJ05kKGCMn+1aCty35pEJayRo+svL7WO0o9QMfGGPfAwek0P3trCwjUcPbdolD9lTIQ4H1h5fa9ISy+xvlluSDclfWOElKGIgin5+KJtig7rvBi6JR6vWC2JRvQL2dZfW7EidDFzok+x6Jl8K8vQb272d9u59juiq8ZtdydXTWvDPaBysXztOuUXXPhUqyI8LueVV+OBwjHVov6gKfZoxFyqNOMUQ9jxXxhoQW3wnub8cBuk3qKiSFT42wDC/9uDB12IfZGY0fLQKBgQDwvOInOHuPkNEaIUOZDQStdIwTaCfNvcACxXPD6m8lY+cun8Y9JdBOz/O4sOEXVsHWAolRGDnyA88J46rlCYrUo+u3G5U4qUux1GHpQR9QMPxk6NgSv6G7xh2Z1SZS9UWhTz74wtoyFHpUiZ9HAJ4llg+D9NonIY2cj/vMHJxxDQKBgQDDYZVoG10ocLfvEp4dz4NsxOw/W1VX94iysfcqWmS2A+3CIUh5Qe8c4hqWBhK0A27X4uOaR4rwW8Rlzy+NNK0uQYXxWJrzrDIoM0R/YQb1MNXOUxPyAGbPtBdmBmWgC7hj4QWICzE5Vx3G0EcLuw1/YMVWsl76rGCW8mfFE0xehwKBgQCCdDixPEBo6fcGC+SPuahBPpjxo01+hkbYuZskHZQhVOPgNiC83hLlwna2LNOtTAw6JqG22kP8S+gT2dWvy935oOKJFV9llwg303lDZ1DKqeD75dnBPysrkA5WYFUmO1eCNGlRcHXBEavAx9sSJNmOUKUTwsm8zsfogXXXg+GauQKBgQCUziu2oLCw7jiIkwtt9PBJ1SmBj5RObS7lunle/n2ZyyA4LJVAFSGCRAqvnGx+QecX8awbgsWlDp9kUwoKZ8ZGZo0XJb7OO6XvzCwtP77G26zbeZbFR90F8Emp4NFhtct39pf551xUKa96DoMtwgcjrpZd03hXPxZJoNG73Vja3QKBgBVy30eq9pttq5SYN4bXZ9evomeBsUZSwpTQ+ugVaiN97wu9AUjE2lAUgWrIVDY0KsYcYg67NIUJTe6O/4HChD35ogbH+tqjalsZgPmPIh5d8syQzPjTfPQAUhXeGe6MIW70NfF7nTLyoikqemol3KxnbtrF2wcK3CTC5EfTOem5";
    private static String publicKeyBase64 = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt7ukVWb6v3tgDTVM1tPbKseTaZpBh+ezPmpvs+NSDJ4STKnja1F8FGweDLxkcC09ZfdYyW/IixeSmnu1C3RJOSyMGv1AN1JKL/9xgTERpBy1g6YyHOIus7D6QYR92J+tordcGK5NNQKG+f7P0sdr7x5tRJw1/2h4F6BvIPpNEzUGygdBqc4AhgyOiBjaF0W3QoeMtHl5yE4iU79S7cVqeikn+t+iF9NO0heb3KIzJo0sG6YTV4NUovwyEwFwF0yu3uGQIWsT4KwD2vg/ECNmEzGi/VMB462THTSg+zZwB1Wg5dc23pWScH7ti+4DWqxKGn4+CO3Bli7HRA/7Dt5j2wIDAQAB";

    /**
     * aes 加密
     *
     * @param data 待加密数据
     * @param key  密钥key
     * @return
     */
    public static String encryptData(String data, String key) {
        AES aes = new AES(Mode.CBC, Padding.PKCS5Padding, key.getBytes(StandardCharsets.UTF_8),
                AES_IV.getBytes(StandardCharsets.UTF_8));
        return aes.encryptBase64(data, StandardCharsets.UTF_8);
    }

    /**
     * aes 解密
     *
     * @param data 待解密数据
     * @param key  密钥key
     * @return
     */
    public static String decryptData(String data, String key) {
        AES aes = new AES(Mode.CBC, Padding.PKCS5Padding, key.getBytes(StandardCharsets.UTF_8),
                AES_IV.getBytes(StandardCharsets.UTF_8));
        return aes.decryptStr(data);
    }


    /**
     * 签名
     * @param data 参数
     * @return 签名
     */
    public static String sign(String data,boolean isHandel) {
        if (isHandel){
           data = handelData(data);
        }
        Sign sign = SecureUtil.sign(SignAlgorithm.SHA256withRSA, privateKeyBase64, null);
        return Base64.encode(sign.sign(StrUtil.bytes(data)));
    }


    /**
     * 验签
     * @param data 参数
     * @param cSign 签名
     * @return 结果
     */
    public static void checkSign(String data,String cSign,boolean isHandel,String key) {
        if (isHandel){
            data = handelData(data);
        }
        Sign sign = SecureUtil.sign(SignAlgorithm.SHA256withRSA, null, StringUtils.isBlank(key)?publicKeyBase64:key);
        boolean verify = sign.verify(StrUtil.bytes(data), Base64.decode(cSign));
        if (!verify){
            throw new ServiceException("验签失败!");
        }
    }

    /**
     * 处理参数中的空值
     * @param data 参数
     * @return 处理后结果
     */
    public static String handelData(String data){
        TreeMap treeMap = JSONObject.parseObject(data, TreeMap.class);
        List<String> list = Lists.newArrayList();
        for (Object o : treeMap.keySet()) {
            Object o1 = treeMap.get(o);
            if (Objects.isNull(o1)||(o1 instanceof String && StringUtils.isBlank((String)o1))){
                continue;
            }
            list.add(o+"="+o1);
        }
        return StringUtils.join(list,"&");
    }

    public static void main(String[] args) {
//        KeyPair pair = SecureUtil.generateKeyPair("RSA", 2048);
//        System.out.println("pri:" + Base64.encode(pair.getPrivate().getEncoded()));
//        System.out.println("pub:" + Base64.encode(pair.getPublic().getEncoded()));
        //{"partnerId":"P0002197","nonce":"a0baa2e27a94","timestamp":1692861203405,"data":"oEqc81ArpxxlnSXk3NgaG+k57G7XrR88IOKOJdgfhn1HFP5xWJxtfWFIMymZnV+4IWMQMGDyGMPHtxwllBMTlw8f3eVKnVjmDjmQBsIkuSwg/RQXsj39RWGaxIhEx8dMaX1vm8Pf/uPm7CJ6wkdB3yTETxxvMQD2eg3aYTPxtKkxUXFcn4n+++VKBLg9zEfEYZHJATW+ihNL9IoE8byZQ9PqXhvicz7tEvc9e9TWWA2bT41oqr4wL4gW1Epoq9gFNf4yXOkWhdaNl7e+2AmD7PZdMxIq9CwjUwrDGA0Mrj/hedpHdr/QHwop6WyoMuVJNPXkbyvboUPQ7aCDxi3EbxRoa+H0Y3tRdMioaA/D7t8="},原始参数:{"merchantId":"M47900107961","payOrderNo":"20230824031321760","transAmount":1,"transType":"1","payType":"4","subOpenid":"o6a4K5NRLxAGD29QCjz7eS39hG_I","subject":"充值","body":"深圳-小程序充值","notifyUrl":"http://h62eix.natappfree.cc/api/wx/user/paySuccess"}#################
//        sign()
    }


}
